package c.x.jy.admin.redisLock;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class RedisLockTool {
	@Autowired
	private RedisTemplate<String, Object> redisTemplate;
	
	private static final String LOCK_SUCCESS = "OK";
	private static final String SET_IF_NOT_EXIST = "NX";
	private static final String SET_WITH_EXPIRE_TIME = "PX";
	private static Long RELEASE_SUCCESS = 1L;
	
	private final static  String  LOCKscript=" local lockSet = redis.call('setnx',KEYS[1],KEYS[2]) if lockSet == 1 then  redis.call('pexpire',KEYS[1],ARGV[1]) else  local value = redis.call('get',KEYS[1]) if(value == KEYS[2])then  lockSet=1;  redis.call('pexpire',KEYS[1],ARGV[1])  end  end return lockSet";

	private final static 	String UNLOCKscript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
	/**
	 * 尝试获取分布式锁
	 * 
	 * @param jedis
	 *            Redis客户端
	 * @param lockKey
	 *            锁
	 * @param requestId
	 *            请求标识
	 * @param expireTime
	 *            超期时间
	 * @return 是否获取成功
	 */
	public   boolean tryGetDistributedLock(RedisTemplate<String, Object> redisTemplate, String lockKey, String requestId, int expireTime) {
		if (redisTemplate == null)
			return false;
	 
	 
		
		//String	  result = (String) jedis.eval(LOCKscript,     Arrays.asList(lockKey) ,  Arrays.asList(requestId,expireTime+"")  );

		List<?> res = redisTemplate.execute((RedisConnection connection) -> connection.eval( LOCKscript .getBytes(),
				ReturnType.MULTI,
                1,
                lockKey.getBytes(),
                requestId.getBytes(),(expireTime+"").getBytes()));
			//result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
			if (res!=null&&!res.isEmpty()&&LOCK_SUCCESS.equals(res.get(0))) {
			 return true;
			} else {
			//	String oldrequestId = jedis.get(lockKey);  
				String oldrequestId =	(String) redisTemplate.opsForValue().get(lockKey);
				return (oldrequestId != null && oldrequestId.equals(requestId))  ;
				 
				 
			}
		 

	}

	/**
	 * 释放分布式锁
	 * 
	 * @param jedis
	 *            Redis客户端
	 * @param lockKey
	 *            锁
	 * @param requestId
	 *            请求标识
	 * @return 是否释放成功
	 */
	public   boolean releaseDistributedLock(RedisTemplate<String, Object> redisTemplate, String lockKey, String requestId) {
		//List<String> list =null;
		//RedisCallback<String> script=null;
		
		if (redisTemplate == null)
			return false;
		//redisTemplate.getConnectionFactory().getConnection().eval(script, returnType, numKeys, keysAndArgs)
		 
		List<?> res = redisTemplate.execute((RedisConnection connection) -> connection.eval( UNLOCKscript .getBytes(),
				ReturnType.MULTI,
                1,
                lockKey.getBytes(),
                requestId.getBytes()));
	//	Object result = jedis.eval(UNLOCKscript, Collections.singletonList(lockKey), Collections.singletonList(requestId));

		if (RELEASE_SUCCESS.equals(res.get(0))) {
			return true;
		}
		return false;

	}

}
